package cn.zwx.zookeeper.config.example.listener;

import cn.zwx.zookeeper.config.example.event.EnvironmentChangeEvent;
import cn.zwx.zookeeper.config.example.source.ZookeeperPropertySourceLocator;
import cn.zwx.zookeeper.config.example.utils.ProcessNestMapUtil;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.curator.framework.recipes.cache.ChildData;
import org.apache.curator.framework.recipes.cache.CuratorCacheListenerBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.Environment;
import org.springframework.core.env.MapPropertySource;

import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.Map;

/**
 * 监听节点数据变化
 * @author zhangwenxue
 */
public class NodeDataChangeCuratorCacheListener implements CuratorCacheListenerBuilder.ChangeListener{

    private static final Logger logger = LoggerFactory.getLogger(ZookeeperPropertySourceLocator.class);


    private Environment environment;
    private ConfigurableApplicationContext applicationContext;

    public NodeDataChangeCuratorCacheListener(Environment environment, ConfigurableApplicationContext applicationContext) {
        this.environment = environment;
        this.applicationContext = applicationContext;
    }

    @Override
    public void event(ChildData oldNode, ChildData node) {

        logger.info("收到数据变更事件");
        ObjectMapper objectMapper=new ObjectMapper();
        try {
            String oldResultData =new String (oldNode.getData(),"gbk");
            String resultData = new String (node.getData(),"gbk");
            logger.info("oldResultData："+oldResultData+"change:"+ resultData);
            //吧json格式的数据转换为map
            Map<String,Object> map= objectMapper.readValue(resultData, Map.class);
            Map<String, Object> objectObjectHashMap = new HashMap<>(8);
            ProcessNestMapUtil.processNestMap("",objectObjectHashMap,map);
            //替换掉原来的PropertySource
            ConfigurableEnvironment cfe=(ConfigurableEnvironment)this.environment;
            MapPropertySource mapPropertySource=new MapPropertySource("configService",objectObjectHashMap);
            cfe.getPropertySources().replace("configService",mapPropertySource);
            //发送一个数据变更事件
            applicationContext.publishEvent(new EnvironmentChangeEvent(this));
            logger.info("数据更新完成");
        } catch (JsonProcessingException | UnsupportedEncodingException e) {
            e.printStackTrace();
        }

    }
}
